package polarizedMF;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import model.MFBig;
import model.PredictBig;
import data.DataBig;
import data.MatrixSize;
import data.Param;
import file.Parsing3ClassesBig;
import file.Parsing3ClassesW2InputsBig;

public class Step8a_Ordinal_SVM_Model {

	/**
	 * @param args
	 * @throws IOException
	 */

	double normalRMSE;
	double idealRMSE;
	
	double normalPosRMSE;
	double normalNeuRMSE;
	double normalNegRMSE;

	double allRMSE;
	double posRMSE;
	double neuRMSE;
	double negRMSE;

	double posPercent;
	double neuPercent;
	double negPercent;

	public Step8a_Ordinal_SVM_Model(String svm_dataset, String dataset,
			String fold, String epsilon, double margin, MatrixSize size,
			Param param) throws IOException {

		String svm_dir = svm_dataset + "fold-" + fold + "\\";
		String dir = dataset + "fold-" + fold + "\\";

		System.out.println("epsilon " + epsilon);
		System.out.println("margin " + margin);

		Parsing3ClassesBig parseTrain = new Parsing3ClassesBig(dir
				+ "smalltrain0" + epsilon + "_data", dir + "smalltrain0"
				+ epsilon + "_sign");

		List<DataBig> train = parseTrain.getList();
		List<DataBig> postrain = parseTrain.getPos();
		List<DataBig> negtrain = parseTrain.getNeg();

		byte k = param.getK();
		double gamma = param.getGamma();
		double lambda = param.getLambda();

		int maxuid = size.getMaxuid();
		int maxiid = size.getMaxiid();

		MFBig mf = new MFBig(train, maxuid, maxiid, k, gamma, lambda);
		MFBig pmf = new MFBig(postrain, maxuid, maxiid, k, gamma, lambda);
		MFBig nmf = new MFBig(negtrain, maxuid, maxiid, k, gamma, lambda);

		Parsing3ClassesBig parseTest = new Parsing3ClassesBig(dir
				+ "smalltest0" + epsilon + "_data", svm_dir + "groundtruth0"
				+ epsilon + "");
		List<DataBig> test = parseTest.getList();
		List<DataBig> postest = parseTest.getPos();
		List<DataBig> negtest = parseTest.getNeg();
		List<DataBig> neutest = parseTest.getNeu();

		PredictBig normalPredict = new PredictBig(test, mf);
		this.normalRMSE = normalPredict.getAllRMSE();

		System.out.println("For ideal case:");

		System.out.printf(
				"Percentage of Pos.Neu.Neg. Test set: %.1f / %.1f / %.1f\n",
				100 * postest.size() / (double) test.size(),
				100 * neutest.size() / (double) test.size(),
				100 * negtest.size() / (double) test.size());

		PredictBig pospred = new PredictBig(postest, mf);
		PredictBig neupred = new PredictBig(neutest, mf);
		PredictBig negpred = new PredictBig(negtest, mf);
		PredictBig signpred = new PredictBig(postest, negtest, neutest, mf,
				pmf, nmf);

		this.normalPosRMSE = pospred.getAllRMSE();
		this.normalNeuRMSE = neupred.getAllRMSE();
		this.normalNegRMSE = negpred.getAllRMSE();
		
		this.idealRMSE = signpred.getAllRMSE();

		System.out
				.printf("RMSE on positive/neutral/negative/whole: %.3f / %.3f / %.3f / %.3f\n",
						pospred.getAllRMSE(), neupred.getAllRMSE(),
						negpred.getAllRMSE(), signpred.getAllRMSE());

		Parsing3ClassesW2InputsBig parseTest2 = new Parsing3ClassesW2InputsBig(
				dir + "smalltest0" + epsilon + "_data", svm_dir + "output0"
						+ epsilon + "", svm_dir + "output0" + epsilon + "_",
				margin);

		List<DataBig> test2 = parseTest2.getList();
		List<DataBig> postest2 = parseTest2.getPos();
		List<DataBig> negtest2 = parseTest2.getNeg();
		List<DataBig> neutest2 = parseTest2.getNeu();

		System.out.println("Pos test size: " + postest2.size());
		System.out.println("Neu test size: " + neutest2.size());
		System.out.println("Neg test size: " + negtest2.size());

		System.out.println("For svm-output signs ");

		posPercent = 100 * postest2.size() / (double) test2.size();
		neuPercent = 100 * neutest2.size() / (double) test2.size();
		negPercent = 100 * negtest2.size() / (double) test2.size();

		System.out.printf(
				"Percentage of Pos.Neu.Neg. Test set: %.1f / %.1f / %.1f\n",
				100 * postest2.size() / (double) test2.size(),
				100 * neutest2.size() / (double) test2.size(),
				100 * negtest2.size() / (double) test2.size());

		PredictBig pospred2 = new PredictBig(postest2, pmf);
		PredictBig neupred2 = new PredictBig(neutest2, mf);
		PredictBig negpred2 = new PredictBig(negtest2, nmf);
		PredictBig signpred2 = new PredictBig(postest2, negtest2, neutest2, mf,
				pmf, nmf);

		posRMSE = pospred2.getAllRMSE();
		neuRMSE = neupred2.getAllRMSE();
		negRMSE = negpred2.getAllRMSE();
		allRMSE = signpred2.getAllRMSE();

		System.out
				.printf("RMSE on positive/neutral/negative/whole: %.3f / %.3f / %.3f / %.3f\n",
						pospred2.getAllRMSE(), neupred2.getAllRMSE(),
						negpred2.getAllRMSE(), signpred2.getAllRMSE());

		posRMSE = signpred2.getPosRMSE();
		neuRMSE = signpred2.getNeuRMSE();
		negRMSE = signpred2.getNegRMSE();

		System.out
				.printf("RMSE on positive/neutral/negative/whole: %.3f / %.3f / %.3f / %.3f\n",
						pospred2.getAllRMSE(), neupred2.getAllRMSE(),
						negpred2.getAllRMSE(), signpred2.getAllRMSE());

		List<DataBig> negPos = new ArrayList<DataBig>();
		List<DataBig> neuPos = new ArrayList<DataBig>();
		List<DataBig> posPos = new ArrayList<DataBig>();
		
		BufferedReader outFile1 = new BufferedReader(new FileReader(svm_dir+"output0"+epsilon));
		BufferedReader dataFile = new BufferedReader(new FileReader(dir+"smalltest0"+epsilon+"_data"));
		BufferedReader signFile = new BufferedReader(new FileReader(dir+"smalltest0"+epsilon+"_sign"));
		
		String dline;
		String sline;
		String line1;
		
		while((line1 = outFile1.readLine()) != null){
			double value1 = Double.parseDouble(line1);
			
			dline = dataFile.readLine();
			String[] fields = dline.split(",");
			int uid = Integer.parseInt(fields[0]);
			int iid = Integer.parseInt(fields[1]);
			double rat = Double.parseDouble(fields[2]);
			
			sline = signFile.readLine();
			double value = Double.parseDouble(sline);
			
			if(value1 > 0){
				if(value > 0){
					posPos.add(new DataBig(uid,iid,rat));
				}
				else if (value < 0){
					negPos.add(new DataBig(uid,iid,rat));					
				}
				else {
					neuPos.add(new DataBig(uid,iid,rat));
				}
			}
		}
		
		outFile1.close();
		dataFile.close();
		signFile.close();
		
		System.out.printf("Pos Pos %.1f%%. Neu Pos %.1f%%. Neg Pos %.1f%%\n", 100*posPos.size()/(double)postest2.size(), 100*neuPos.size()/(double)postest2.size(), 100*negPos.size()/(double)postest2.size());
		
		PredictBig posPosPred = new PredictBig(posPos, pmf);
		PredictBig neuPosPred = new PredictBig(neuPos, pmf);
		PredictBig negPosPred = new PredictBig(negPos, pmf);
		
		System.out.printf("Pos Pos %.3f. Neu Pos %.3f. Neg Pos %.3f\n", posPosPred.getAllRMSE(), neuPosPred.getAllRMSE(), negPosPred.getAllRMSE());
		
		/*
		 * List<DataBig> negPos = new ArrayList<DataBig>(); List<DataBig> negNeu
		 * = new ArrayList<DataBig>(); List<DataBig> negNeg = new
		 * ArrayList<DataBig>();
		 * 
		 * BufferedReader outFile1 = new BufferedReader(new
		 * FileReader(svm_dir+"output0"+epsilon)); BufferedReader outFile2 = new
		 * BufferedReader(new FileReader(svm_dir+"output0"+epsilon+"_"));
		 * BufferedReader dataFile = new BufferedReader(new
		 * FileReader(dir+"smalltest0"+epsilon+"_data")); BufferedReader
		 * signFile = new BufferedReader(new
		 * FileReader(dir+"smalltest0"+epsilon+"_sign")); // BufferedReader
		 * signFile = new BufferedReader(new
		 * FileReader(svm_dir+"groundtruth0"+epsilon)); String dline; String
		 * sline; String line1; while((line1 = outFile1.readLine()) != null){
		 * double value1 = Double.parseDouble(line1);
		 * 
		 * dline = dataFile.readLine(); String[] fields = dline.split(","); int
		 * uid = Integer.parseInt(fields[0]); int iid =
		 * Integer.parseInt(fields[1]); double rat =
		 * Double.parseDouble(fields[2]);
		 * 
		 * sline = signFile.readLine(); double value =
		 * Double.parseDouble(sline);
		 * 
		 * if(value1 > 0) { if(value1 > margin) { //predicted positive } else {
		 * //predicted neutral } } else { String line2 = outFile2.readLine();
		 * double value2 = Double.parseDouble(line2);
		 * 
		 * if(value2 > margin) { //predicted negative if (value < 0) {
		 * //actually negative negNeg.add(new DataBig(uid,iid,rat)); }
		 * 
		 * else if(value > 0) { //actually positive negPos.add(new
		 * DataBig(uid,iid,rat)); } else { //actually neutral negNeu.add(new
		 * DataBig(uid,iid,rat)); } } } } outFile1.close(); outFile2.close();
		 * dataFile.close(); signFile.close();
		 * 
		 * System.out.printf(
		 * "Number of positive/neutral/negative ratings predicted as negative ratings: %d / %d / %d / %d\n"
		 * , negPos.size(), negNeu.size(), negNeg.size(), negtest2.size());
		 * 
		 * PredictBig negPosPred = new PredictBig(negPos, nmf); PredictBig
		 * negNeuPred = new PredictBig(negNeu, nmf); PredictBig negNegPred = new
		 * PredictBig(negNeg, nmf);
		 * 
		 * System.out.printf(
		 * "Use negative MF to predict positive/neutral/negative ratings predicted as negative ratings: %.3f / %.3f / %.3f / %.3f\n"
		 * , negPosPred.getRmse(), negNeuPred.getRmse(), negNegPred.getRmse(),
		 * negpred2.getRmse());
		 */
	}

	public double getNormalRMSE() {
		return normalRMSE;
	}

	public double getIdealRMSE() {
		return idealRMSE;
	}

	public double getNormalPosRMSE() {
		return normalPosRMSE;
	}

	public double getNormalNeuRMSE() {
		return normalNeuRMSE;
	}

	public double getNormalNegRMSE() {
		return normalNegRMSE;
	}

	public double getPosRMSE() {
		return posRMSE;
	}

	public double getNeuRMSE() {
		return neuRMSE;
	}

	public double getNegRMSE() {
		return negRMSE;
	}

	public double getAllRMSE() {
		return allRMSE;
	}

	public double getPosPercent() {
		return posPercent;
	}

	public double getNeuPercent() {
		return neuPercent;
	}

	public double getNegPercent() {
		return negPercent;
	}

}
